import javassist.*;

/**
 * @author tanghailan
 * @date 2022-01-20 11:54:03
 * @description
 */
public class Test {
  public static void main(String[] args) throws Exception {
    ClassPool pool = ClassPool.getDefault();

    // 创建一个空的类
    CtClass cc = pool.makeClass("com.ygz.demo.javassist.JavassistObj1");

    // 新增一个字段名为name  String 类型
    CtField name = new CtField(pool.getCtClass("java.lang.String"), "name", cc);
    // 访问级别是 private
    name.setModifiers(Modifier.PRIVATE);
    // 初始值是 "jingchuan"
    cc.addField(name, CtField.Initializer.constant("jingchuan"));

    // 新增一个字段名为id  int 类型
    CtField id = new CtField(pool.getCtClass("int"), "id", cc);
    // 访问级别是 private
    id.setModifiers(Modifier.PRIVATE);
    // 初始值是 1
    cc.addField(id, CtField.Initializer.constant(1));

    // 给name字段添加 get、set 方法
    cc.addMethod(CtNewMethod.setter("setName", name));
    cc.addMethod(CtNewMethod.getter("getName", name));

    // 给id字段添加 get、set 方法
    cc.addMethod(CtNewMethod.setter("setId", id));
    cc.addMethod(CtNewMethod.getter("getId", id));

    // 添加无参的构造函数
    CtConstructor cons = new CtConstructor(new CtClass[] {}, cc);
    cons.setBody("{name = \"jingchuanya\"; id = 1;}");
    cc.addConstructor(cons);

    // 添加有参的构造函数
    cons = new CtConstructor(new CtClass[] {pool.get("int"), pool.get("java.lang.String")}, cc);
    // $0=this / $1,$2,$3... 代表方法参数
    cons.setBody("{$0.id = $1;$0.name = $2;}");
    cc.addConstructor(cons);

    // 6. 创建一个名为printToString方法，无参数，无返回值，输出id和name值
    CtMethod ctMethod = new CtMethod(CtClass.voidType, "printToString", new CtClass[] {}, cc);
    ctMethod.setModifiers(Modifier.PUBLIC);
    ctMethod.setBody("{System.out.println(name);System.out.println(id);}");
    cc.addMethod(ctMethod);

    // todo 这里改成自己的路径
    cc.writeFile("D:\\devSoft\\code\\backend\\learn-demo\\Test\\src\\main\\java");

    Class<?> aClass = cc.toClass();
    Object o = aClass.newInstance();
    o.getClass().getMethod("printToString", new Class[] {}).invoke(o);
  }
}
